package com.digitaldreamers.framework.scene;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;

import com.digitaldreamers.framework.BaseConstants;
import com.digitaldreamers.framework.network.IConnectionHandler;
import com.digitaldreamers.framework.network.IConnectionHandler.IOnDataReceivedListener;

public abstract class ManagedNetworkScene extends ManagedScene implements Runnable, IOnDataReceivedListener {
	private boolean mIsRunning;
	private ArrayList<byte[]> mDataList;
    private Thread mHandlePacketThread;
	protected IConnectionHandler mConnectionHandler;
	
	public ManagedNetworkScene() {
		this(0f);
	}
	
	public ManagedNetworkScene(float pMinLoadingScreenTime) {
		super(pMinLoadingScreenTime);
	}
	
	@Override
	public void onShowScene() {
        mDataList = new ArrayList<byte[]>();
        startReceivingData();
		mConnectionHandler = IConnectionHandler.instance;
		mConnectionHandler.addOnDataReceivedListener(this);
	}
	
	@Override
	public void onUnloadScene() {
		mConnectionHandler.removeOnDataReceivedListener(this);
		stopReceivingData();
	}
	
	@Override
	public void onDataReceived(byte[] pData) {
		addPacket(pData);
	}
	
	@Override
    public void run() {
        while (mIsRunning) {
            if (mDataList.size() > 0) {
                byte[] data = removePacket(0);
                handlePacket(data);
            }
            try {
                Thread.sleep(BaseConstants.SLEEP_TIME);
            } catch (InterruptedException e) {
            	e.printStackTrace();
            }
        }
    }
	
	private synchronized void addPacket(byte[] pData) {
        mDataList.add(pData);
    }
	
	private synchronized byte[] removePacket(int pIndex) {
        return mDataList.remove(pIndex);
    }
	
	private synchronized void startReceivingData() {
        if (!mIsRunning) {
            mIsRunning = true;
            mHandlePacketThread = new Thread(this);
            mHandlePacketThread.start();
        }
    }
    
    private synchronized void stopReceivingData() {
    	if (mIsRunning) {
            mIsRunning = false;
	        try {
	        	mHandlePacketThread.join();
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        
	        mDataList.clear();
	        mHandlePacketThread = null;
    	}
    }
    
    private void handlePacket(byte[] pData) {
    	ByteArrayInputStream BAIS = new ByteArrayInputStream(pData);
        DataInputStream DIS = new DataInputStream(BAIS);
    	try {
            int packetID = DIS.readInt();
            processPacket(packetID, pData);
    	} catch (Exception e) {
    		e.printStackTrace();
    	} finally {
            try {
				DIS.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
            DIS = null;
    	}
    }
    
    protected abstract void processPacket(int pPacketId, byte[] pData);
}
